Friday, 17 July 2020

Can a form tell if there are any modal windows open?

How, being inside the main form of my WinForm app can I tell if there are any modal windows/dialogs open that belong to the main form?


Answers:


Long story short: opening a modal form is blocks execution on the main form as long as the modal window is open, so your main form can never check to see if its opened any modal forms until after the modal form has closed. In other words, your question is based on a misunderstanding of how modal forms work, so its moot altogether.

For what its worth, it is possible to tell if there are any modal forms open:

foreach (Form f in Application.OpenForms)
{
    if (f.Modal)
    {
        // do stuff
    }
}

Answers:


if (this.Visible && !this.CanFocus)
{
    // modal child windows are open
}

Answers:


You maybe can use the events for EnterThreadModal and LeaveThreadModal. Here is an example how you can do it:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Application.EnterThreadModal += new EventHandler(Application_EnterThreadModal);
            Application.LeaveThreadModal += new EventHandler(Application_LeaveThreadModal);

            Application.Run(new Form1());
        }

        private static void Application_EnterThreadModal(object sender, EventArgs e)
        {
            IsModalDialogOpen = true;
        }

        private static void Application_LeaveThreadModal(object sender, EventArgs e)
        {
            IsModalDialogOpen = false;
        }

        public static bool IsModalDialogOpen { get; private set; }
    }
}

Answers:


Timers still run and fire events.
Example that works...

public partial class Form1 : Form
{
    Form2 f2 = new Form2();
    public Form1()
    {
        InitializeComponent();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        f2.UpdateData(DateTime.Now.ToString());
        if (!f2.Visible) f2.ShowDialog();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        f2.ShowDialog();
        MessageBox.Show('Done');
    }
}

Answers:


If you Google a bit you will find that Form.ShowDialog() disables other forms to prevent user input to those forms of the current one. But most everything else (like timers and other events from sources external to the displayed form) continues to run.


Answers:


This is an illustration why this answer is correct and the assumptions made in this answer are sometimes wrong.

if (MyForm.CanFocus == false && MyForm.Visible == true)
{
    // we are modal            
}

This works for modal shown sub Forms and for MessageBoxes.


Some demo code:

private void modalTest_Click(object sender, EventArgs e)
{
    // Timer which fires 100ms after the first message box is shown
    System.Windows.Forms.Timer canFocusTimer = new System.Windows.Forms.Timer();
    canFocusTimer.Tick += CanFocusTimer_Tick;
    canFocusTimer.Interval = 100;
    canFocusTimer.Start();
    
    // First MessageBox shows that CanFocus == true
    MessageBox.Show($"First MessageBox: { nameof(this.CanFocus) } == { this.CanFocus }");
}

private void CanFocusTimer_Tick(object sender, EventArgs e)
{
    (sender as System.Windows.Forms.Timer).Stop();

    // Even though there is already a MessageBox shown the second gets
    // displayed. But now CanFocus == false
    MessageBox.Show($"Second MessageBox: { nameof(this.CanFocus) } == { this.CanFocus }");
}

Result:

enter image description here


Answers:


Converting transparent gif / png to jpeg using java

I'd like to convert gif images to jpeg using Java. It works great for most images, but I have a simple transparent gif image:

Input gif image http://img292.imageshack.us/img292/2103/indexedtestal7.gif

[In case the image is missing: it's a blue circle with transparent pixels around it]

When I convert this image using the following code:

File file = new File('indexed_test.gif');
BufferedImage image = ImageIO.read(file);
File f = new File('indexed_test.jpg');
ImageIO.write(image, 'jpg', f);

This code works without throwing an Exception, but results an invalid jpeg image:

Output jpeg image

[In case the image is missing: IE cannot show the jpeg, Firefox shows the image with invalid colors.]

I'm using Java 1.5.

I also tried converting the sample gif to png with gimp and using the png as an input for the Java code. The result is the same.

Is it a bug in the JDK? How can I convert images correctly preferably without 3rd party libraries?

UPDATE:

Answers indicate that jpeg conversion cannot handle transparency correctly (I still think that this is a bug) and suggest a workaround for replacing transparent pixels with predefined color. Both of the suggested methods are quite complex, so I've implemented a simpler one (will post as an answer). I accept the first published answer with this workaround (by Markus). I don't know which implementation is the better. I go for the simplest one still I found a gif where it's not working.


Answers:


JPEG has no support for transparency. So even when you get the circle color correctly you will still have a black or white background, depending on your encoder and/or renderer.


Answers:


The problem (at least with png to jpg conversion) is that the color scheme isn't the same, because jpg doesn't support transparency.

What we've done successfully is something along these lines (this is pulled from various bits of code - so please forgive the crudeness of the formatting):

File file = new File('indexed_test.gif');
BufferedImage image = ImageIO.read(file);
int width = image.getWidth();
int height = image.getHeight();
BufferedImage jpgImage;

//you can probably do this without the headless check if you just use the first block
if (GraphicsEnvironment.isHeadless()) {
  if (image.getType() == BufferedImage.TYPE_CUSTOM) {
      //coerce it to  TYPE_INT_ARGB and cross fingers -- PNGs give a    TYPE_CUSTOM and that doesn't work with
      //trying to create a new BufferedImage
     jpgImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
  } else {
     jpgImage = new BufferedImage(width, height, image.getType());
  }
} else {
     jgpImage =   GraphicsEnvironment.getLocalGraphicsEnvironment().
        getDefaultScreenDevice().getDefaultConfiguration().
        createCompatibleImage(width, height, image.getTransparency()); 
}

//copy the original to the new image
Graphics2D g2 = null;
try {
 g2 = jpg.createGraphics();

 g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
                    RenderingHints.VALUE_INTERPOLATION_BICUBIC);
 g2.drawImage(image, 0, 0, width, height, null);
}
finally {
   if (g2 != null) {
       g2.dispose();
   }
}

File f = new File('indexed_test.jpg');

ImageIO.write(jpgImage, 'jpg', f);

This works for png to jpg and gif to jpg. And you will have a white background where the transparent bits were. You can change this by having g2 fill the image with another color before the drawImage call.


Answers:


As already mentioned in the UPDATE of the question I've implemented a simpler way of replacing transparent pixels with predefined color:

public static BufferedImage fillTransparentPixels( BufferedImage image, 
                                                   Color fillColor ) {
    int w = image.getWidth();
    int h = image.getHeight();
    BufferedImage image2 = new BufferedImage(w, h, 
        BufferedImage.TYPE_INT_RGB);
    Graphics2D g = image2.createGraphics();
    g.setColor(fillColor);
    g.fillRect(0,0,w,h);
    g.drawRenderedImage(image, null);
    g.dispose();
    return image2;
}

and I call this method before jpeg conversion in this way:

if( inputImage.getColorModel().getTransparency() != Transparency.OPAQUE) {
    inputImage = fillTransparentPixels(inputImage, Color.WHITE);
}

Answers:


3 months late, but I am having a very similar problem (although not even loading a gif, but simply generating a transparent image - say, no background, a colored shape - where when saving to jpeg, all colors are messed up, not only the background)

Found this bit of code in this rather old thread of the java2d-interest list, thought I'd share, because after a quick test, it is much more performant than your solution:

        final WritableRaster raster = img.getRaster();
        final WritableRaster newRaster = raster.createWritableChild(0, 0, img.getWidth(), img.getHeight(), 0, 0, new int[]{0, 1, 2});

        // create a ColorModel that represents the one of the ARGB except the alpha channel
        final DirectColorModel cm = (DirectColorModel) img.getColorModel();
        final DirectColorModel newCM = new DirectColorModel(cm.getPixelSize(), cm.getRedMask(), cm.getGreenMask(), cm.getBlueMask());

        // now create the new buffer that we'll use to write the image
        return new BufferedImage(newCM, newRaster, false, null);

Unfortunately, I can't say I understand exactly what it does ;)


Answers:


For Java 6 (and 5 too, I think):

BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
g = bufferedImage.createGraphics();
//Color.WHITE estes the background to white. You can use any other color
g.drawImage(image, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), Color.WHITE, null);

Answers:


If you create a BufferedImage of type BufferedImage.TYPE_INT_ARGB and save to JPEG weird things will result. In my case the colors are scewed into orange. In other cases the produced image might be invalid and other readers will refuse loading it.

But if you create an image of type BufferedImage.TYPE_INT_RGB then saving it to JPEG works fine.

I think this is therefore a bug in Java JPEG image writer - it should write only what it can without transparency (like what .NET GDI+ does). Or in the worst case thrown an exception with a meaningful message e.g. 'cannot write an image that has transparency'.


Answers:


BufferedImage originalImage = ImageIO.read(getContent());
BufferedImage newImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);

    for (int x = 0; x < originalImage.getWidth(); x++) {
        for (int y = 0; y < originalImage.getHeight(); y++) {
            newImage.setRGB(x, y, originalImage.getRGB(x, y));
        }
    }
 ImageIO.write(newImage, "jpg", f);

7/9/2020 Edit: added imageIO.write


Answers:


Creating a new DOM element from an HTML string using built-in DOM methods or Prototype

I have an HTML string representing an element: '<li>text</li>'. I'd like to append it to an element in the DOM (a ul in my case). How can I do this with Prototype or with DOM methods?

(I know i could do this easily in jQuery, but unfortunately we're not using jQuery.)


Answers:


Note: most current browsers support HTML <template> elements, which provide a more reliable way of turning creating elements from strings. See Mark Amery's answer below for details.

For older browsers, and node/jsdom: (which doesn't yet support <template> elements at the time of writing), use the following method. It's the same thing the libraries use to do to get DOM elements from an HTML string (with some extra work for IE to work around bugs with its implementation of innerHTML):

function createElementFromHTML(htmlString) {
  var div = document.createElement('div');
  div.innerHTML = htmlString.trim();

  // Change this to div.childNodes to support multiple top-level nodes
  return div.firstChild; 
}

Note that unlike HTML templates this won't work for some elements that cannot legally be children of a <div>, such as <td>s.

If you're already using a library, I would recommend you stick to the library-approved method of creating elements from HTML strings:


Answers:


With Prototype, you can also do:

HTML:

<ul id='mylist'></ul>

JS:

$('mylist').insert('<li>text</li>');

Answers:


Here's my code, and it works:

function parseTableHtml(s) { // s is string
    var div = document.createElement('table');
    div.innerHTML = s;

    var tr = div.getElementsByTagName('tr');
    // ...
}

Answers:


Newer DOM implementations have range.createContextualFragment, which does what you want in a framework-independent way.

It's widely supported. To be sure though, check its compatibility down in the same MDN link, as it will be changing. As of May 2017 this is it:

Feature         Chrome   Edge   Firefox(Gecko)  Internet Explorer   Opera   Safari
Basic support   (Yes)    (Yes)  (Yes)           11                  15.0    9.1.2

Answers:


This will work too:

$('<li>').text('hello').appendTo('#mylist');

It feels more like a jquery way with the chained function calls.


Answers:


var jtag = $j.li({ child:'text' }); // Represents: <li>text</li>
var htmlContent = $('mylist').html();
$('mylist').html(htmlContent + jtag.html());

Use jnerator


Answers:


Late but just as a note;

It's possible to add a trivial element to target element as a container and remove it after using.

// Tested on chrome 23.0, firefox 18.0, ie 7-8-9 and opera 12.11.

<div id='div'></div>

<script>
window.onload = function() {
    var foo, targetElement = document.getElementById('div')
    foo = document.createElement('foo')
    foo.innerHTML = '<a href='#' target='_self'>Text of A 1.</a> '+
                    '<a href='#' onclick='return !!alert(this.innerHTML)'>Text of <b>A 2</b>.</a> '+
                    '<hr size='1' />'
    // Append 'foo' element to target element
    targetElement.appendChild(foo)

    // Add event
    foo.firstChild.onclick = function() { return !!alert(this.target) }

    while (foo.firstChild) {
        // Also removes child nodes from 'foo'
        targetElement.insertBefore(foo.firstChild, foo)
    }
    // Remove 'foo' element from target element
    targetElement.removeChild(foo)
}
</script>

Answers:


Heres a simple way to do it:

String.prototype.toDOM=function(){
  var d=document
     ,i
     ,a=d.createElement('div')
     ,b=d.createDocumentFragment();
  a.innerHTML=this;
  while(i=a.firstChild)b.appendChild(i);
  return b;
};

var foo='<img src='//placekitten.com/100/100'>foo<i>bar</i>'.toDOM();
document.body.appendChild(foo);

Answers:


For the heck of it I thought I'd share this over complicated but yet simple approach I came up with... Maybe someone will find something useful.

/*Creates a new element - By Jamin Szczesny*/
function _new(args){
    ele = document.createElement(args.node);
    delete args.node;
    for(x in args){ 
        if(typeof ele[x]==='string'){
            ele[x] = args[x];
        }else{
            ele.setAttribute(x, args[x]);
        }
    }
    return ele;
}

/*You would 'simply' use it like this*/

$('body')[0].appendChild(_new({
    node:'div',
    id:'my-div',
    style:'position:absolute; left:100px; top:100px;'+
          'width:100px; height:100px; border:2px solid red;'+
          'cursor:pointer; background-color:HoneyDew',
    innerHTML:'My newly created div element!',
    value:'for example only',
    onclick:'alert('yay')'
}));

Answers:


For certain html fragments like <td>test</td>, div.innerHTML, DOMParser.parseFromString and range.createContextualFragment (without the right context) solutions mentioned in other answers here, won't create the <td> element.

jQuery.parseHTML() handles them properly (I extracted jQuery 2's parseHTML function into an independent function that can be used in non-jquery codebases).

If you are only supporting Edge 13+, it is simpler to just use the HTML5 template tag:

function parseHTML(html) {
    var t = document.createElement('template');
    t.innerHTML = html;
    return t.content.cloneNode(true);
}

var documentFragment = parseHTML('<td>Test</td>');

Answers:


function domify (str) {
  var el = document.createElement('div');
  el.innerHTML = str;

  var frag = document.createDocumentFragment();
  return frag.appendChild(el.removeChild(el.firstChild));
}

var str = '<div class='foo'>foo</div>';
domify(str);

Answers:


HTML 5 introduced the <template> element which can be used for this purpose (as now described in the WhatWG spec and MDN docs).

A <template> element is used to declare fragments of HTML that can be utilized in scripts. The element is represented in the DOM as a HTMLTemplateElement which has a .content property of DocumentFragment type, to provide access to the template's contents. This means that you can convert an HTML string to DOM elements by setting the innerHTML of a <template> element, then reaching into the template's .content property.

Examples:

/**
 * @param {String} HTML representing a single element
 * @return {Element}
 */
function htmlToElement(html) {
    var template = document.createElement('template');
    html = html.trim(); // Never return a text node of whitespace as the result
    template.innerHTML = html;
    return template.content.firstChild;
}

var td = htmlToElement('<td>foo</td>'),
    div = htmlToElement('<div><span>nested</span> <span>stuff</span></div>');

/**
 * @param {String} HTML representing any number of sibling elements
 * @return {NodeList} 
 */
function htmlToElements(html) {
    var template = document.createElement('template');
    template.innerHTML = html;
    return template.content.childNodes;
}

var rows = htmlToElements('<tr><td>foo</td></tr><tr><td>bar</td></tr>');

Note that similar approaches that use a different container element such as a div don't quite work. HTML has restrictions on what element types are allowed to exist inside which other element types; for instance, you can't put a td as a direct child of a div. This causes these elements to vanish if you try to set the innerHTML of a div to contain them. Since <template>s have no such restrictions on their content, this shortcoming doesn't apply when using a template.

However, template is not supported in some old browsers. As of January 2018, Can I use... estimates 90% of users globally are using a browser that supports templates. In particular, no version of Internet Explorer supports them; Microsoft did not implement template support until the release of Edge.

If you're lucky enough to be writing code that's only targeted at users on modern browsers, go ahead and use them right now. Otherwise, you may have to wait a while for users to catch up.


Answers:


I am using this method (Works in IE9+), although it will not parse <td> or some other invalid direct childs of body:

function stringToEl(string) {
    var parser = new DOMParser(),
        content = 'text/html',
        DOM = parser.parseFromString(string, content);

    // return element
    return DOM.body.childNodes[0];
}

stringToEl('<li>text</li>'); //OUTPUT: <li>text</li>

Answers:


No need for any tweak, you got a native API:

const toNodes = html =>
    new DOMParser().parseFromString(html, 'text/html').body.childNodes[0]

Answers:


You can create valid DOM nodes from a string using:

document.createRange().createContextualFragment()

The following example adds a button element in the page taking the markup from a string:

let html = '<button type='button'>Click Me!</button>';
let fragmentFromString = function (strHTML) {
  return document.createRange().createContextualFragment(strHTML);
}
let fragment = fragmentFromString(html);
document.body.appendChild(fragment);


Answers:


You can use the following function to convert the text 'HTML' to the element

function htmlToElement(html)
{
  var element = document.createElement('div');
  element.innerHTML = html;
  return(element);
}
var html='<li>text and html</li>';
var e=htmlToElement(html);


Answers:


I added a Document prototype that creates an element from string:

Document.prototype.createElementFromString = function (str) {
    const element = new DOMParser().parseFromString(str, 'text/html');
    const child = element.documentElement.querySelector('body').firstChild;
    return child;
};

Answers:


Use insertAdjacentHTML(). It works with all current browsers, even with IE11.

var mylist = document.getElementById('mylist');
mylist.insertAdjacentHTML('beforeend', '<li>third</li>');
<ul id='mylist'>
 <li>first</li>
 <li>second</li>
</ul>


Answers:


Here is working code for me

I wanted to convert 'Text' string to HTML element

var diva = UWA.createElement('div');
diva.innerHTML = '<a href='http://wwww.example.com'>Text</a>';
var aelement = diva.firstChild;

Answers:


HTML5 & ES6

<template>

Demo

'use strict';

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @description HTML5 Template
 * @augments
 * @example
 *
 */

/*

<template>
    <h2>Flower</h2>
    <img src='https://www.w3schools.com/tags/img_white_flower.jpg'>
</template>


<template>
    <div class='myClass'>I like: </div>
</template>

*/

const showContent = () => {
    // let temp = document.getElementsByTagName('template')[0],
    let temp = document.querySelector(`[data-tempalte='tempalte-img']`),
        clone = temp.content.cloneNode(true);
    document.body.appendChild(clone);
};

const templateGenerator = (datas = [], debug = false) => {
    let result = ``;
    // let temp = document.getElementsByTagName('template')[1],
    let temp = document.querySelector(`[data-tempalte='tempalte-links']`),
        item = temp.content.querySelector('div');
    for (let i = 0; i < datas.length; i++) {
        let a = document.importNode(item, true);
        a.textContent += datas[i];
        document.body.appendChild(a);
    }
    return result;
};

const arr = ['Audi', 'BMW', 'Ford', 'Honda', 'Jaguar', 'Nissan'];

if (document.createElement('template').content) {
    console.log('YES! The browser supports the template element');
    templateGenerator(arr);
    setTimeout(() => {
        showContent();
    }, 0);
} else {
    console.error('No! The browser does not support the template element');
}
@charset 'UTf-8';

/* test.css */

:root {
    --cololr: #000;
    --default-cololr: #fff;
    --new-cololr: #0f0;
}

[data-class='links'] {
    color: white;
    background-color: DodgerBlue;
    padding: 20px;
    text-align: center;
    margin: 10px;
}
<!DOCTYPE html>
<html lang='zh-Hans'>

<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <meta http-equiv='X-UA-Compatible' content='ie=edge'>
    <title>Template Test</title>
    <!--[if lt IE 9]>
        <script src='https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js'></script>
    <![endif]-->
</head>

<body>
    <section>
        <h1>Template Test</h1>
    </section>
    <template data-tempalte='tempalte-img'>
        <h3>Flower Image</h3>
        <img src='https://www.w3schools.com/tags/img_white_flower.jpg'>
    </template>
    <template data-tempalte='tempalte-links'>
        <h3>links</h3>
        <div data-class='links'>I like: </div>
    </template>
    <!-- js -->
</body>

</html>


Answers:


To enhance furthermore the useful .toDOM() snippet that we can find in different places, we can now safely use backticks (template literals).

So we can have single and double quotes in the foo html declaration.

This behave like heredocs for those familiar with the term.

This can be enhanced furthermore with variables, to make complex templating:

Template literals are enclosed by the back-tick () (grave accent) character instead of double or single quotes. Template literals can contain placeholders. These are indicated by the dollar sign and curly braces (${expression}). The expressions in the placeholders and the text between them get passed to a function. The default function just concatenates the parts into a single string. If there is an expression preceding the template literal (tag here), this is called a 'tagged template'. In that case, the tag expression (usually a function) gets called with the processed template literal, which you can then manipulate before outputting. To escape a back-tick in a template literal, put a backslash before the back-tick.

String.prototype.toDOM=function(){
  var d=document,i
     ,a=d.createElement('div')
     ,b=d.createDocumentFragment()
  a.innerHTML = this
  while(i=a.firstChild)b.appendChild(i)
  return b
}

// Using template litterals
var a = 10, b = 5
var foo=`
<img 
  onclick='alert('The future start today!')'   
  src='//placekitten.com/100/100'>
foo${a + b}
  <i>bar</i>
    <hr>`.toDOM();
document.body.appendChild(foo);
img {cursor: crosshair}

So, why not use directly .innerHTML +=? By doing so, the whole DOM is being recalculated by the browser, it's much slower.

https://caniuse.com/template-literals


Answers:


var msg = 'test' jQuery.parseHTML(msg)


Answers:


Fastest solution to render DOM from string:

let render = (relEl, tpl, parse = true) => {
  if (!relEl) return;
  const range = document.createRange();
  range.selectNode(relEl);
  const child = range.createContextualFragment(tpl);
  return parse ? relEl.appendChild(child) : {relEl, el};
};

And here u can check performance for DOM manipulation React vs native JS

Now u can simply use:

let element = render(document.body, `
<div style='font-size:120%;line-height:140%'>
  <p class='bold'>New DOM</p>
</div>
`);

And of course in near future u use references from memory cause var 'element' is your new created DOM in your document.

And remember 'innerHTML=' is very slow :/


Answers:


Why don't do with native js?

    var s='<span class='text-muted' style='font-size:.75em; position:absolute; bottom:3px; left:30px'>From <strong>Dan's Tools</strong></span>'
    var e=document.createElement('div')
    var r=document.createRange();
    r.selectNodeContents(e)
    var f=range.createContextualFragment(s);
    e.appendChild(f);
    e = e.firstElementChild;

Answers:


Answer

  • Create a Template
  • Set the Template's innerHTML to your string
  • Create an Array of Template's children
  • Return child, children, or

function toElement(s='',c,t,l='length'){t=document.createElement('template');
t.innerHTML=s.trim();c=[...t.content.childNodes];return c[l]>1?c:c[0]||'';}



console.log(toElement());
console.log(toElement(''));
console.log(toElement('    '));
console.log(toElement('<td>With td</td>'));
console.log(toElement('<tr><td>With t</td></tr>'));
console.log(toElement('<tr><td>foo</td></tr><tr><td>bar</td></tr>'));
console.log(toElement('<div><span>nested</span> <span>stuff</span></div>'));


Answers:


Setting up foreign keys in phpMyAdmin?

I'm setting up a database using phpMyAdmin. I have two tables (foo and bar), indexed on their primary keys. I am trying to create a relational table (foo_bar) between them, using their primary keys as foreign keys.

I created these tables as MyISAM, but have since changed all three to InnoDB, because I read that MyISAM doesn't support foreign keys. All id fields are INT(11).

When I choose the foo_bar table, click the "relation view" link, and try to set the FK columns to be database.foo.id and database.bar.id, it says "No index defined!" beside each column.

What am I missing?

Clarification/Update

For the sake of simplicity, I want to keep using phpMyAdmin. I am currently using XAMPP, which is easy enough to let me focus on the PHP/CSS/Javascript, and it comes with phpMyAdmin.

Also, although I haven't been able to set up explicit foreign keys yet, I do have a relational table and can perform joins like this:

SELECT * 
FROM foo 
INNER JOIN foo_bar 
ON foo.id = foo_bar.foo_id 
INNER JOIN bar
ON foo_bar.bar_id = bar.id;

It just makes me uncomfortable not to have the FKs explicitly defined in the database.


Answers:


InnoDB allows you to add a new foreign key constraint to a table by using ALTER TABLE:

ALTER TABLE tbl_name
    ADD [CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]

On the other hand, if MyISAM has advantages over InnoDB in your context, why would you want to create foreign key constraints at all. You can handle this on the model level of your application. Just make sure the columns which you want to use as foreign keys are indexed!


Answers:


If you want to use phpMyAdmin to set up relations, you have to do 2 things. First of all, you have to define an index on the foreign key column in the referring table (so foo_bar.foo_id, in your case). Then, go to relation view (in the referring table) and select the referred column (so in your case foo.id) and the on update and on delete actions.

I think foreign keys are useful if you have multiple tables linked to one another, in particular, your delete scripts will become very short if you set the referencing options correctly.

EDIT: Make sure both of the tables have the InnoDB engine selected.


Answers:


phpMyAdmin lets you define foreign keys using their 'relations' view. But since, MySQL only supports foreign constraints on 'INNO DB' tables, the first step is to make sure the tables you are using are of that type.

To setup a foreign key so that the PID column in a table named CHILD references the ID column in a table named PARENT, you can do the following:

  1. For both tables, go to the operations tab and change their type to 'INNO DB'
  2. Make sure ID is the primary key (or at least an indexed column) of the PARENT table.
  3. In the CHILD table, define an index for the PID column.
  4. While viewing the structure tab of the CHILD table, click the 'relation view' link just above the 'add fields' section.
  5. You will be given a table where each row corresponds to an indexed column in your CLIENT table. The first dropdown in each row lets you choose which TABLE->COLUMN the indexed column references. In the row for PID, choose PARENT->ID from the dropdown and click GO.

By doing an export on the CHILD table, you should see a foreign key constraint has been created for the PID column.


Answers:


Don't forget that the two columns should have the same data type.

for example if one column is of type INT and the other is of type tinyint you'll get the following error:

Error creating foreign key on [PID column] (check data types)


Answers:


This is a summary of a Wikipedia article. It specifies the different types of relationships you can stipulate in PHPmyadmin. I am putting it here because it is relevant to @Nathan's comment on setting the foreign keys options for 'on update/delete' but is too large for a comment - hope it helps.

CASCADE

Whenever rows in the master (referenced) table are deleted (resp. updated), the respective rows of the child (referencing) table with a matching foreign key column will get deleted (resp. updated) as well. This is called a cascade delete (resp. update[2]).

RESTRICT

A value cannot be updated or deleted when a row exists in a foreign key table that references the value in the referenced table. Similarly, a row cannot be deleted as long as there is a reference to it from a foreign key table.

NO ACTION

NO ACTION and RESTRICT are very much alike. The main difference between NO ACTION and RESTRICT is that with NO ACTION the referential integrity check is done after trying to alter the table. RESTRICT does the check before trying to execute the UPDATE or DELETE statement. Both referential actions act the same if the referential integrity check fails: the UPDATE or DELETE statement will result in an error.

SET NULL

The foreign key values in the referencing row are set to NULL when the referenced row is updated or deleted. This is only possible if the respective columns in the referencing table are nullable. Due to the semantics of NULL, a referencing row with NULLs in the foreign key columns does not require a referenced row.

SET DEFAULT

Similar to SET NULL, the foreign key values in the referencing row are set to the column default when the referenced row is updated or deleted.


Answers:


For those new to database .... and need to ALTER an existing table. A lot things seem to be pretty straightforward, but there is always something ... between A and B.

Before anything else, take a look at this.

  1. Make sure you have P_ID (parent ID on both parent and child table).
  2. Of course it will be already filled in the parent. Not necessarily in the child in a true and final way. So for instance P_ID #3 (maybe many times in the child table will be pointing to original P_ID at parent table).
  3. Go to SQL tab (I am using phpMyAdmin, should be similar in other ones) and do this command:

    ALTER TABLE child_table_name    
    ADD FOREIGN KEY (P_ID)   
    REFERENCES parent_table_name (P_ID)
    
  4. Click on child table, than structure, finally on relational view. Finish your DB planning there. There was a nice answer before this one about cascade, restrict, etc. Of course it could be done by commands...


Answers:


Foreign key means a non prime attribute of a table referes the prime attribute of another *in phpMyAdmin* first set the column you want to set foreign key as an index

then click on RELATION VIEW

there u can find the options to set foreign key


Answers:


In phpmyadmin, you can assign Foreign key simply by its GUI. Click on the table and go to Structure tab. find the Relation View on just bellow of table (shown in below image).

enter image description here

You can assign the forging key from the list box near by the primary key.(See image below). and save

enter image description here

corresponding SQL query automatically generated and executed.


Answers:


Step 1: You have to add the line: default-storage-engine = InnoDB under the [mysqld] section of your mysql config file (my.cnf or my.ini depending on your OS) and restart the mysqld service. enter image description here

Step 2: Now when you create the table you will see the type of table is: InnoDB

enter image description here

Step 3: Create both Parent and Child table. Now open the Child table and select the column U like to have the Foreign Key: Select the Index Key from Action Label as shown below.

enter image description here

Step 4: Now open the Relation View in the same child table from bottom near the Print View as shown below.

enter image description here Step 5: Select the column U like to have the Foreign key as Select the Parent column from the drop down. dbName.TableName.ColumnName

Select appropriate Values for ON DELETE and ON UPDATE enter image description here


Answers:


From the official MySQL documentation at https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html:

MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan.


Answers:


First set Storage Engine as InnoDB

First set Storage Engine as InnoDB

then the relation view option enable in structure menu

then the relation view option enable


Answers:


This is old thread but answer because if useful to anyone.

Step 1. Your Db Storage Engine set to InnoDB

Step 2. Create Primary Table

here customer is primary table and customer_id is primary key

enter image description here

Step 3. create foreign key table and give index

here we have customer_addresses as related table and store customer addresses, so here customer_id relation with customer table

we can select index directly when create table as below

enter image description here

If you forgot to give index when create a table, then you can give index from the structure tab of table as below.

enter image description here

Step 4. Once index give to the field, Go to structure tab and click on Relation View as shown in below pic

enter image description here

Step 5. Now select the ON DELETE and ON UPDATE what you want to do, Select column from current table, select DB (SAME DB), select relation table and primary key from that table as shown in below pic and Save it

enter image description here

Now check if relation are give successfully, go to foreign table data list and click on foreign key value, you will redirect to primary table record, then relation made successfully.


Answers:


Newer versions of phpMyAdmin don't have the 'Relation View' option anymore, in which case you'll have to execute a statement to achieve the same thing. For example

ALTER TABLE employees
    ADD CONSTRAINT fk_companyid FOREIGN KEY (companyid)
    REFERENCES companies (id)
    ON DELETE CASCADE;

In this example, if a row from companies is deleted, all employees with that companyid are also deleted.


Answers:


Make sure you have selected your mysql storage engine as Innodb and not MYISAM as innodb storage engine supports foreign keys in Mysql.

Steps to create foreign keys in phpmyadmin:

  1. Tap on structure for the table which will have the foreign key.
  2. Create INDEX for the column you want to use as foreign key.
  3. Tap on Relation view, placed below the table structure

relation view

  1. In the Relation view page, you can see select options in front of the field (which was made an INDEX).

setting foreign key relation

UPDATE CASCADE specifies that the column will be updated when the referenced column is updated, and DELETE CASCADE specified rows will be deleted when the referenced rows are deleted.

Alternatively, you can also trigger sql query for the same

ALTER TABLE table_name
ADD CONSTRAINT fk_foreign_key_name
FOREIGN KEY (foreign_key_name)
REFERENCES target_table(target_key_name);

Answers:


Case insensitive 'Contains(string)'

Is there a way to make the following return true?

string title = 'ASTRINGTOTEST';
title.Contains('string');

There doesn't seem to be an overload that allows me to set the case sensitivity.. Currently I UPPERCASE them both, but that's just silly (by which I am referring to the i18n issues that come with up- and down casing).

UPDATE
This question is ancient and since then I have realized I asked for a simple answer for a really vast and difficult topic if you care to investigate it fully.
For most cases, in mono-lingual, English code bases this answer will suffice. I'm suspecting because most people coming here fall in this category this is the most popular answer.
This answer however brings up the inherent problem that we can't compare text case insensitive until we know both texts are the same culture and we know what that culture is. This is maybe a less popular answer, but I think it is more correct and that's why I marked it as such.


Answers:


You could always just up or downcase the strings first.

string title = 'string':
title.ToUpper().Contains('STRING')  // returns true

Oops, just saw that last bit. A case insensitive compare would *probably* do the same anyway, and if performance is not an issue, I don't see a problem with creating uppercase copies and comparing those. I could have sworn that I once saw a case-insensitive compare once...


Answers:


You could use the String.IndexOf Method and pass StringComparison.OrdinalIgnoreCase as the type of search to use:

string title = 'STRING';
bool contains = title.IndexOf('string', StringComparison.OrdinalIgnoreCase) >= 0;

Even better is defining a new extension method for string:

public static class StringExtensions
{
    public static bool Contains(this string source, string toCheck, StringComparison comp)
    {
        return source?.IndexOf(toCheck, comp) >= 0;
    }
}

Note, that null propagation ?. is available since C# 6.0 (VS 2015), for older versions use

if (source == null) return false;
return source.IndexOf(toCheck, comp) >= 0;

USAGE:

string title = 'STRING';
bool contains = title.Contains('string', StringComparison.OrdinalIgnoreCase);

Answers:


You can use IndexOf() like this:

string title = 'STRING';

if (title.IndexOf('string', 0, StringComparison.CurrentCultureIgnoreCase) != -1)
{
    // The string exists in the original
}

Since 0 (zero) can be an index, you check against -1.

MSDN

The zero-based index position of value if that string is found, or -1 if it is not. If value is String.Empty, the return value is 0.


Answers:


Alternative solution using Regex:

bool contains = Regex.IsMatch('StRiNG to search', Regex.Escape('string'), RegexOptions.IgnoreCase);

Answers:


StringExtension class is the way forward, I've combined a couple of the posts above to give a complete code example:

public static class StringExtensions
{
    /// <summary>
    /// Allows case insensitive checks
    /// </summary>
    public static bool Contains(this string source, string toCheck, StringComparison comp)
    {
        return source.IndexOf(toCheck, comp) >= 0;
    }
}

Answers:


One issue with the answer is that it will throw an exception if a string is null. You can add that as a check so it won't:

public static bool Contains(this string source, string toCheck, StringComparison comp)
{
    if (string.IsNullOrEmpty(toCheck) || string.IsNullOrEmpty(source))
        return true;

    return source.IndexOf(toCheck, comp) >= 0;
} 

Answers:


Use this:

string.Compare('string', 'STRING', new System.Globalization.CultureInfo('en-US'), System.Globalization.CompareOptions.IgnoreCase);

Answers:


I know that this is not the C#, but in the framework (VB.NET) there is already such a function

Dim str As String = 'UPPERlower'
Dim b As Boolean = InStr(str, 'UpperLower')

C# variant:

string myString = 'Hello World';
bool contains = Microsoft.VisualBasic.Strings.InStr(myString, 'world');

Answers:


This is clean and simple.

Regex.IsMatch(file, fileNamestr, RegexOptions.IgnoreCase)

Answers:


To test if the string paragraph contains the string word (thanks @QuarterMeister)

culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0

Where culture is the instance of CultureInfo describing the language that the text is written in.

This solution is transparent about the definition of case-insensitivity, which is language dependent. For example, the English language uses the characters I and i for the upper and lower case versions of the ninth letter, whereas the Turkish language uses these characters for the eleventh and twelfth letters of its 29 letter-long alphabet. The Turkish upper case version of 'i' is the unfamiliar character 'İ'.

Thus the strings tin and TIN are the same word in English, but different words in Turkish. As I understand, one means 'spirit' and the other is an onomatopoeia word. (Turks, please correct me if I'm wrong, or suggest a better example)

To summarise, you can only answer the question 'are these two strings the same but in different cases' if you know what language the text is in. If you don't know, you'll have to take a punt. Given English's hegemony in software, you should probably resort to CultureInfo.InvariantCulture, because it'll be wrong in familiar ways.


Answers:


Using a RegEx is a straight way to do this:

Regex.IsMatch(title, 'string', RegexOptions.IgnoreCase);

Answers:


The InStr method from the VisualBasic assembly is the best if you have a concern about internationalization (or you could reimplement it). Looking at in it dotNeetPeek shows that not only does it account for caps and lowercase, but also for kana type and full- vs. half-width characters (mostly relevant for Asian languages, although there are full-width versions of the Roman alphabet too). I'm skipping over some details, but check out the private method InternalInStrText:

private static int InternalInStrText(int lStartPos, string sSrc, string sFind)
{
  int num = sSrc == null ? 0 : sSrc.Length;
  if (lStartPos > num || num == 0)
    return -1;
  if (sFind == null || sFind.Length == 0)
    return lStartPos;
  else
    return Utils.GetCultureInfo().CompareInfo.IndexOf(sSrc, sFind, lStartPos, CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth);
}

Answers:


OrdinalIgnoreCase, CurrentCultureIgnoreCase or InvariantCultureIgnoreCase?

Since this is missing, here are some recommendations about when to use which one:

Dos

  • Use StringComparison.OrdinalIgnoreCase for comparisons as your safe default for culture-agnostic string matching.
  • Use StringComparison.OrdinalIgnoreCase comparisons for increased speed.
  • Use StringComparison.CurrentCulture-based string operations when displaying the output to the user.
  • Switch current use of string operations based on the invariant culture to use the non-linguistic StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase when the comparison is
    linguistically irrelevant (symbolic, for example).
  • Use ToUpperInvariant rather than ToLowerInvariant when normalizing strings for comparison.

Don'ts

  • Use overloads for string operations that don't explicitly or implicitly specify the string comparison mechanism.
  • Use StringComparison.InvariantCulture -based string
    operations in most cases; one of the few exceptions would be
    persisting linguistically meaningful but culturally-agnostic data.

Based on these rules you should use:

string title = 'STRING';
if (title.IndexOf('string', 0, StringComparison.[YourDecision]) != -1)
{
    // The string exists in the original
}

whereas [YourDecision] depends on the recommendations from above.

link of source: http://msdn.microsoft.com/en-us/library/ms973919.aspx


Answers:


Just like this:

string s='AbcdEf';
if(s.ToLower().Contains('def'))
{
    Console.WriteLine('yes');
}

Answers:


This is quite similar to other example here, but I've decided to simplify enum to bool, primary because other alternatives are normally not needed. Here is my example:

public static class StringExtensions
{
    public static bool Contains(this string source, string toCheck, bool bCaseInsensitive )
    {
        return source.IndexOf(toCheck, bCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) >= 0;
    }
}

And usage is something like:

if( 'main String substring'.Contains('SUBSTRING', true) )
....

Answers:


The trick here is to look for the string, ignoring case, but to keep it exactly the same (with the same case).

 var s='Factory Reset';
 var txt='reset';
 int first = s.IndexOf(txt, StringComparison.InvariantCultureIgnoreCase) + txt.Length;
 var subString = s.Substring(first - txt.Length, txt.Length);

Output is 'Reset'


Answers:


if ('strcmpstring1'.IndexOf(Convert.ToString('strcmpstring2'), StringComparison.CurrentCultureIgnoreCase) >= 0){return true;}else{return false;}

Answers:


You can use string.indexof () function. This will be case insensitive


Answers:


Simple way for newbie:

title.ToLower().Contains('string');//of course 'string' is lowercase.

Answers:


public static class StringExtension
{
    #region Public Methods

    public static bool ExContains(this string fullText, string value)
    {
        return ExIndexOf(fullText, value) > -1;
    }

    public static bool ExEquals(this string text, string textToCompare)
    {
        return text.Equals(textToCompare, StringComparison.OrdinalIgnoreCase);
    }

    public static bool ExHasAllEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index]) == false) return false;
        return true;
    }

    public static bool ExHasEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index])) return true;
        return false;
    }

    public static bool ExHasNoEquals(this string text, params string[] textArgs)
    {
        return ExHasEquals(text, textArgs) == false;
    }

    public static bool ExHasNotAllEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index])) return false;
        return true;
    }

    /// <summary>
    /// Reports the zero-based index of the first occurrence of the specified string
    /// in the current System.String object using StringComparison.InvariantCultureIgnoreCase.
    /// A parameter specifies the type of search to use for the specified string.
    /// </summary>
    /// <param name='fullText'>
    /// The string to search inside.
    /// </param>
    /// <param name='value'>
    /// The string to seek.
    /// </param>
    /// <returns>
    /// The index position of the value parameter if that string is found, or -1 if it
    /// is not. If value is System.String.Empty, the return value is 0.
    /// </returns>
    /// <exception cref='ArgumentNullException'>
    /// fullText or value is null.
    /// </exception>
    public static int ExIndexOf(this string fullText, string value)
    {
        return fullText.IndexOf(value, StringComparison.OrdinalIgnoreCase);
    }

    public static bool ExNotEquals(this string text, string textToCompare)
    {
        return ExEquals(text, textToCompare) == false;
    }

    #endregion Public Methods
}

Answers:


if you want to check if your passed string is in string then there is a simple method for that.

string yourStringForCheck= 'abc';
string stringInWhichWeCheck= 'Test abc abc';

bool isContained = stringInWhichWeCheck.ToLower().IndexOf(yourStringForCheck.ToLower()) > -1;

This boolean value will return if the string is contained or not


Answers:


These are the easiest solutions.

  1. By Index of

    string title = 'STRING';
    
    if (title.IndexOf('string', 0, StringComparison.CurrentCultureIgnoreCase) != -1)
    {
        // contains 
    }
    
  2. By Changing case

    string title = 'STRING';
    
    bool contains = title.ToLower().Contains('string')
    
  3. By Regex

    Regex.IsMatch(title, 'string', RegexOptions.IgnoreCase);
    

Answers:


.NET Core 2.0+ only (as of now)

.NET Core has had a pair of methods to deal with this since version 2.0 :

  • String.Contains(Char, StringComparison)
  • String.Contains(String, StringComparison)

Example:

'Test'.Contains('test', System.StringComparison.CurrentCultureIgnoreCase);

In time, they will probably make their way into the .NET Standard and, from there, into all the other implementations of the Base Class Library.


Answers:


Just to build on the answer here, you can create a string extension method to make this a little more user-friendly:

    public static bool ContainsIgnoreCase(this string paragraph, string word)
    {
        return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
    }

Answers:


As simple and works

title.ToLower().Contains('String'.ToLower())

Answers:


Similar to previous answers (using an extension method) but with two simple null checks (C# 6.0 and above):

public static bool ContainsIgnoreCase(this string source, string substring)
{
    return source?.IndexOf(substring ?? "", StringComparison.OrdinalIgnoreCase) >= 0;
}

If source is null, return false (via null-propagation operator ?.)

If substring is null, treat as an empty string and return true (via null-coalescing operator ??)

The StringComparison can of course be sent as a parameter if needed.


Answers: